﻿namespace Centido.Core.Test
{
    using System;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    /// <summary>
    ///   Working as an ordinary user.
    /// </summary>
    [TestClass]
    public class WorkingAsUserTest
    {
        /// <summary>
        ///   The current domain name.
        /// </summary>
        public const string DomainName = "FullAdminRights";

        /// <summary>
        ///   The current domain.
        /// </summary>
        private Domain _domain;

        /// <summary>
        ///   A sample table.
        /// </summary>
        private Table _table;

        /// <summary>
        ///   A sample user domain.
        /// </summary>
        private Domain _userDomain;


        /// <summary>
        ///  Initializes a test.
        /// </summary>
        [TestInitialize]
        public void TestInitialize()
        {
            _domain = Domain.Build(DomainConfiguration.Load(DomainName));
            _domain.HasRecycleBin = new Random(Environment.TickCount).Next() % 2 == 1;

            _domain.DeleteAll();

            var userPassword = StringProperty.RandomPassword();
            var user = _domain.AddUser(StringProperty.RandomIdentifier(), userPassword);
            user.CanLogon = true;

            _userDomain = _domain.Logon(user.Name, userPassword);

            _table = _domain.AddTable(StringProperty.RandomIdentifier());

            _table.AddColumn(StringProperty.RandomIdentifier(), ColumnType.BigInteger);
            _table.AddColumn(StringProperty.RandomIdentifier(), ColumnType.Binary);
            _table.AddColumn(StringProperty.RandomIdentifier(), ColumnType.Boolean);
            _table.AddColumn(StringProperty.RandomIdentifier(), ColumnType.DateTime);
            _table.AddColumn(StringProperty.RandomIdentifier(), ColumnType.Decimal);
            _table.AddColumn(StringProperty.RandomIdentifier(), ColumnType.Enumeration);
            _table.AddColumn(StringProperty.RandomIdentifier(), ColumnType.Guid);
            _table.AddColumn(StringProperty.RandomIdentifier(), ColumnType.Integer);
            _table.AddColumn(StringProperty.RandomIdentifier(), ColumnType.Reference);
            _table.AddColumn(StringProperty.RandomIdentifier(), ColumnType.SmallInteger);
            _table.AddColumn(StringProperty.RandomIdentifier(), ColumnType.String);
            _table.AddColumn(StringProperty.RandomIdentifier(), ColumnType.Text);

            _table.GrantAll(user);
        }

        /// <summary>
        ///  Cleans a test up.
        /// </summary>
        [TestCleanup]
        public void TestCleanup()
        {
            _domain.DeleteAll();
        }

        /// <summary>
        ///   Reading the schema structure.
        /// </summary>
        [TestMethod]
        public void ReadingSchemaStructure()
        {
            // ReSharper disable UnusedVariable
            
            // Searching table by id
            _userDomain.GetTable(Guid.NewGuid());

            // Searching table by name
            _userDomain.GetTable(StringProperty.RandomIdentifier());


            // Reading dbms info
            var metadataMajorVersion = _userDomain.Dbms.MetadataMajorVersion;
            var metadataMinorVersion = _userDomain.Dbms.MetadataMinorVersion;

            var productName = _userDomain.Dbms.ProductName;
            var productVersion = _userDomain.Dbms.ProductVersion;

            var columnRenaming = _userDomain.Dbms.HasColumnRenaming;

            var recycleBin = _userDomain.HasRecycleBin;

            // Enumerating tables
            foreach (var table in _userDomain.Tables)
            {
                var tableName = table.Name;

                var tableDisplayNameSingular = table.DisplayName;
                var tableDescription = table.Description;

                // Searching column by id
                table.GetColumn(Guid.NewGuid());

                // Searching column by name
                table.GetColumn(StringProperty.RandomIdentifier());

                foreach (var column in table.Columns)
                {
                    var columnName = column.Name;
                    var columnDisplayName = column.DisplayName;
                    var columnDescription = column.Description;
                    var columnOrderIndex = column.OrderIndex;
                    var columnType = column.IsSystem;
                    var columnIsNotNull = column.IsNotNull;

                    if (column is RefColumn)
                    {
                        var refChecking = (column as RefColumn).HasReferenceChecking;
                    }
                    else if (column is EnumColumn)
                    {
                        var valueChecking = (column as EnumColumn).HasValueChecking;
                    }
                }

                foreach (var index in table.Indexes)
                {
                    var indexIsUnique = index.IsUnique;

                    foreach (var indexColumn in index.Columns)
                    {
                    }
                }
            }

            // ReSharper restore UnusedVariable
        }

        /// <summary>
        ///  Reading security settings.
        /// </summary>
        [TestMethod]
        public void ReadingSecurity()
        {
            // Reading current user
            var currUser = _userDomain.CurrentUser;

            var recycleBinIsEnabled = _userDomain.HasRecycleBin;

            var currUserName = currUser.Name;
            var currUserDisplayName = currUser.DisplayName;
            currUser.DisplayName = StringProperty.RandomIdentifier();
            var canChangeSchema = currUser.CanChangeSchema;
            var canChangeSecurity = currUser.CanChangeSecurity;
            var accessRights = currUser.TableAccessRights;

            foreach(var unit in currUser.Units)
            {
                var unitDisplayName = unit.DisplayName;

                var children = unit.ChildUnits;
                var parents = unit.Parents;
                var unitUsers = unit.Users;

                var result = unit.ContainsUser("my_user");
                result = unit.ContainsUnit(Guid.NewGuid());
            }

            foreach (var user in _userDomain.Users)
            {
                var userDisplayName = user.DisplayName;
            }

            foreach (var table in _userDomain.Tables)
            {
                var canDo = _userDomain.CurrentUser.CanDo(table, DataAction.Select);
            }
        }
    }
}